module("framework.mvc.view.BaseView", package.seeall)

---@class BaseView : UserDataDispose
local BaseView = class("BaseView", UserDataDispose)

function BaseView:ctor()
    self.viewGO = nil
    self.viewContainer = nil
    self.viewParam = nil
    self.viewName = nil

    --tab view 特有的变量
    self.tabContainer = nil
    self.rootGO = nil

    --动态 add child views
    self._childViews = nil
    self._tryCallResultDict = nil --记录try调度成功失败，可用于判断界面打开是否储存在异常的依据
end



------------------internal methods------------------
function BaseView:onInitViewInternal()
    self._has_onInitView = true
    if self._childViews then
        for _, child in ipairs(self._childViews) do
            child.viewGO = self.viewGO
            child.viewContainer = self.viewContainer
            child.viewName = self.viewName
        end
    end
    self:_internalCall("onInitView")
end
function BaseView:addEventsInternal()
    self._has_addEvents = true
    self:_internalCall("addEvents")
end
function BaseView:onOpenInternal()
    self._has_onOpen = true
    self:_internalCall("onOpen")
end
function BaseView:onOpenFinishInternal()
    self._has_onOpenFinish = true
    self:_internalCall("onOpenFinish")
end
function BaseView:onUpdateParamInternal()
    self:_internalCall("onUpdateParam")
end
function BaseView:onClickModalMaskInternal()
    self:_internalCall("onClickModalMask")
end
function BaseView:onCloseInternal()
    self._has_onOpen = false
    self._has_onOpenFinish = false
    self:_internalCall("onClose")
end
function BaseView:onCloseFinishInternal()
    self:_internalCall("onCloseFinish")
end
function BaseView:removeEventsInternal()
    self._has_addEvents = false
    self:_internalCall("removeEvents")
end
function BaseView:onDestroyViewInternal()
    self._has_onInitView = false
    self:_internalCall("onDestroyView")
    self._childViews = nil
    --self:__onDispose()
    self:tryCallMethodName("__onDispose")
end
function BaseView:_internalCall(method)
    --先将child view列表复制一份，当前对象的调用执行完，再遍历。
    --避免当前调用过程中添加child，或者遍历过程中添加child，导致重复执行child的调用
    local temp = self._childViews and tabletool.copy(self._childViews)
    if temp then
        for _, child in ipairs(temp) do
            child[method .. "Internal"](child)
        end
    end
    --self[method](self)
    --保证View生命周期函数执行，增加try catch处理 2025-1-22
    self:tryCallMethodName(method)
end
------------------internal methods end------------------

-- 增加try catch调度，并且其记录成功失败
function BaseView:tryCallMethodName(method)
    local isOk,result = xpcall(self[method], __G__TRACKBACK__, self)
    self._tryCallResultDict = self._tryCallResultDict or {}
    self._tryCallResultDict[method] = isOk
    return isOk,result
end

-- 是否存在异常的调度
function BaseView:isHasTryCallFail()

    if self._tryCallResultDict then 
        for method,isOk in pairs(self._tryCallResultDict) do 
            if isOk == false then 
                return true
            end
        end
    end
    local temp = self._childViews
    if temp then
        local count = #temp 
        for i=1,count do 
            local child = temp[i]
            if child and child:isHasTryCallFail() then 
                return true 
            end
        end
    end

    return false
end


------------------override methods------------------
--子界面初始化，此时资源已经加载好了，viewGO可用
function BaseView:onInitView()
end
--子界面添加生命周期内的事件监听
function BaseView:addEvents()
end
--子界面打开阶段
function BaseView:onOpen()
end
--子界面打开完成
function BaseView:onOpenFinish()
end
--界面处于open状态，又被open了，参数就会传到这里来
function BaseView:onUpdateParam()
end
--点击了模态框的Mask
function BaseView:onClickModalMask()
end
--子界面关闭阶段
function BaseView:onClose()
end
--子界面关闭完成
function BaseView:onCloseFinish()
end
--界面生命周期结束，需要移除事件监听
function BaseView:removeEvents()
end
--界面销毁阶段
function BaseView:onDestroyView()
end
------------------override methods end------------------



--通过资源路径，获取资源实例对象
function BaseView:getResInst(resPath, parentGO, name)
    return self.viewContainer:getResInst(resPath, parentGO, name)
end

--关闭自己
function BaseView:closeThis()
    ViewMgr.instance:closeView(self.viewName,nil,true)
end

--动态添加一个view（必须继承自BaseView）作为子view，生命周期与当前view同步
function BaseView:addChildView(view)
    if not view then return end
    if not isTypeOf(view, BaseView) then
        logError("addChildView fail, view must inherited from BaseView: " .. (view.__cname or "nil"))
        return
    end
    self._childViews = self._childViews or {}
    if not tabletool.indexOf(self._childViews, view) then
        table.insert(self._childViews, view)
        view:__onInit()
        view.viewGO = self.viewGO
        view.viewContainer = self.viewContainer
        view.viewName = self.viewName
        if self._has_onInitView then
            view:onInitViewInternal()
        end
        if self._has_addEvents then
            view:addEventsInternal()
        end
        if self._has_onOpen then
            view:onOpenInternal()
        end
        if self._has_onOpenFinish then
            view:onOpenFinishInternal()
        end
    end
end

return BaseView
